package com.basic_test;

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

/**
 * 包括元素的定位、操作以及等待的基础语法
 */

public class first_auto_test {

    private ChromeDriver chromedriver;

    /**
     * 创建驱动对象
     */
    public void start_auto_test() throws InterruptedException {
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--remote-allow-origins=*");
        this.chromedriver = new ChromeDriver(options);

//        EdgeOptions options = new EdgeOptions();
//        options.addArguments("--remote-allow-origins=*");
//        EdgeDriver driver = new EdgeDriver(options);
    }

    /**
     * 退出浏览器以及驱动
     * @throws InterruptedException
     */
    public void quit_auto_test() throws InterruptedException {
//        chromedriver.close();
        chromedriver.quit();
//        close也可以关闭窗口。两者的区别是：
//        close方法关闭当前的浏览器窗口，quit方法不仅关闭窗口，还会彻底的退出webdriver，释放与driver
//        server之间的连接。所以简单来说quit是更加彻底的close，quit会更好的释放资源。
    }

    /**
     * 定位元素
     * @throws InterruptedException
     */
    public void localization_element() throws InterruptedException {
        chromedriver.get("https://www.google.com/");
        Thread.sleep(1000);

//        css选择器
//        String test_text = chromedriver.findElement(By.cssSelector("#SIvCob")).getText();
//        System.out.println("test_text : " + test_text);
//        Thread.sleep(1000);

//        xpath选择器
//        语法：层级：/子级//跳级
//        属性：@
//        函数：contains()
        WebElement search_box =  chromedriver.findElement(By.xpath("//*[@id=\"APjFqb\"]"));
        search_box.sendKeys("我的世界" + Keys.ENTER);
        String test_text = chromedriver.findElement(By.xpath("//*[@id=\"kp-wp-tab-overview\"]/div[1]/div/div/div/div/div/div/div/div/div/div[1]/div/span/a/h3")).getText();
        System.out.println("期望的文本结果是 : 欢迎来到Minecraft 官方网站| Minecraft   实际的文本结果是 : " + test_text);
        Thread.sleep(1000);

//        不管是css选择器还是xpath选择器都必须要求定位到得元素是唯一的,不然就会报错
    }

    /**
     * 操作元素
     */
    public void element_operation() throws InterruptedException {
//        chromedriver.get("https://www.google.com/");
//        Thread.sleep(1000);
//
//        WebElement search_box =  chromedriver.findElement(By.xpath("//*[@id=\"APjFqb\"]"));
//        search_box.sendKeys("我的世界");
//        search_box.submit();
////        对于没有搜索按钮的搜索框,就需要submit,不能使用click
////        search_box.click();
//        Thread.sleep(3000);
//
//        //就算搜索框的xpath和之前的页面是一样的,但是到了新的页面也需要重新进行定位,不然会报错
//        chromedriver.findElement(By.xpath("//*[@id=\"APjFqb\"]")).clear();
////        search_box.clear();
//
//        chromedriver.findElement(By.xpath("//*[@id=\"APjFqb\"]")).sendKeys("steam");
//
////        对于有搜索按钮的搜索框,submit和click都可以进行使用
//        chromedriver.findElement(By.xpath("//*[@id=\"tsf\"]/div[1]/div[1]/div[2]/button/div")).click();
////        chromedriver.findElement(By.xpath("//*[@id=\"tsf\"]/div[1]/div[1]/div[2]/button/div")).submit();
//        Thread.sleep(1000);

        /**
         * 点击：click 提交：submit
         * click和submit都可以操作按钮
         * 可以click不一定可以submit,但是页面的任何元素都可以click
         * 但是如果表单没有操作的按钮,这个时候submit就没有用,只有click才有用
         */

        chromedriver.get("https://www.baidu.com/");
        Thread.sleep(1000);

//        获取文本getText
        String test_text = chromedriver.findElement(By.xpath("//*[@id=\"hotsearch-content-wrapper\"]/li[1]/a/span[2]")).getText();
        System.out.println("期望的文本结果是 : 向“新”而行   实际的文本结果是 : " + test_text);

//        为什么这里就不能获取到百度一下的文本,因为这里的百度一下是标签的属性(属于是标签内),getText只能获取标签之外的文本
        test_text  = chromedriver.findElement(By.xpath("//*[@id=\"su\"]")).getText();
        System.out.println("期望的文本结果是 : 百度一下   实际的文本结果是 : " + test_text);

        //如何获取属性值
        String attribute_one = chromedriver.findElement(By.xpath("//*[@id=\"su\"]")).getAttribute("type");
        String attribute_two = chromedriver.findElement(By.xpath("//*[@id=\"su\"]")).getAttribute("id");
        String attribute_three = chromedriver.findElement(By.xpath("//*[@id=\"su\"]")).getAttribute("value");
        String attribute_four = chromedriver.findElement(By.xpath("//*[@id=\"su\"]")).getAttribute("class");

        System.out.println("type : " + attribute_one + " id : " + attribute_two + " value : " + attribute_three + " class : " + attribute_four);

        //这样就可以获取到想要的百度一下的文本
        test_text  = chromedriver.findElement(By.xpath("//*[@id=\"su\"]")).getAttribute("value");
        System.out.println("期望的文本结果是 : 百度一下   实际的文本结果是 : " + test_text);
        Thread.sleep(1000);
    }

    /**
     * 元素的等待
     * 一般的浏览器,渲染页面都会有一个时间,如果页面渲染完成之前,你就去找某一个元素,那么有可能是找不到的,这个时候就会报错
     * 所以我们就需要等待,等待元素渲染完成之后,这个时候我们再去寻找元素,就可以找到
     * 但是可能是我浏览器有优化,或者是selenium有优化(也有可能是我上面创建驱动启动参数的问题),每次我都不需要手动写代码,等待页面渲染完成
     * 它会自动帮我等待页面渲染完成(相当于隐式等待),所以我没有测试出等待的错误,但是不保证其他环境下也是一样的,所以我们下面的代码都是以没有优化为前提的
     */
    public void element_wait() throws InterruptedException {
        chromedriver.get("https://www.google.com/");

//        强制等待
//        chromedriver.findElement(By.xpath("//*[@id=\"APjFqb\"]")).sendKeys("steam");
//        chromedriver.findElement(By.xpath("//*[@id=\"APjFqb\"]")).submit();
////        不添加等待的话页面没有染完成，导致最后一步的查找页面元素失败，添加强制等待3s再进行页面元素查找，结果成功
//        Thread.sleep(3000);
//        chromedriver.findElement(By.xpath("//*[@id=\"rso\"]/div[1]/div/div/div/div/div/div/div/div[1]/div/span/a/h3")).click();

//        隐式等待
//        设置隐式等待时间为2s
//        chromedriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
//        chromedriver.findElement(By.xpath("//*[@id=\"APjFqb\"]")).sendKeys("steam");
//        chromedriver.findElement(By.xpath("//*[@id=\"APjFqb\"]")).submit();
//        chromedriver.findElement(By.xpath("//*[@id=\"rso\"]/div[1]/div/div/div/div/div/div/div/div[1]/div/span/a/h3")).click();

//        显式等待
        chromedriver.findElement(By.xpath("//*[@id=\"APjFqb\"]")).sendKeys("steam");
        chromedriver.findElement(By.xpath("//*[@id=\"APjFqb\"]")).submit();
//        设置显式等待时间
        WebDriverWait webDriverWait = new WebDriverWait(chromedriver, Duration.ofSeconds(5));
//        设置显示等待的条件,在规定的时间内,如果等待的条件还没有满足,那么就会抛出异常
//        presenceOfElementLocated用来判断这个元素是否存在
        webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"rso\"]/div[1]/div/div/div/div/div/div/div/div[1]/div/span/a/h3")));
//        textToBe用来对比定位的元素的文本是否和预设的文本一致
        webDriverWait.until(ExpectedConditions.textToBe(By.xpath("//*[@id=\"rso\"]/div[1]/div/div/div/div/div/div/div/div[1]/div/span/a/h3"), "Welcome to Steam"));
    }

    /**
     * 同时使用隐式等待(5s)和显式等待(10s),那么最后显式等待的部分将会覆盖掉隐式等待的部分,所以会等待10s
     */
    public void wait_test() {
        chromedriver.get("https://www.google.com/");

        System.out.println(System.currentTimeMillis());
        chromedriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));

        WebDriverWait webDriverWait = new WebDriverWait(chromedriver, Duration.ofSeconds(10));

        chromedriver.findElement(By.xpath("//*[@id=\"APjFqb\"]")).sendKeys("我的世界" + Keys.ENTER);

        try {
            webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"kp-wp-tab-overview\"]/div[1]/div/div/div/div/div/div/div/div/div/div[1]/div/span/a/h")));
        }catch (Exception e) {
            System.out.println("not found element!");
        }
        System.out.println(System.currentTimeMillis());
    }

}
